home *** CD-ROM | disk | FTP | other *** search
/ STraTOS 1997 April & May / STraTOS 1 - 1997 April & May.iso / CD01 / INTERNET / SITES / GRAHAM / XAAES_S.ZIP / XAAES / J_RECT.C < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-03  |  5.5 KB  |  268 lines

  1. /*
  2.  * XaAES - XaAES Ain't the AES
  3.  *
  4.  * A multitasking AES replacement for MiNT
  5.  *
  6.  */
  7.  
  8. #include <VDI.H>
  9. #include <MINTBIND.H>
  10. #include <memory.h>
  11. #include "XA_DEFS.H"
  12. #include "XA_TYPES.H"
  13. #include "XA_GLOBL.H"
  14. #include "K_DEFS.H"
  15. #include "C_WINDOW.H"
  16. #include "EVENTS.H"
  17. #include "rectlist.h"
  18.  
  19. #define max(x,y)    (((x)>(y))?(x):(y))
  20. #define min(x,y)    (((x)<(y))?(x):(y))
  21.  
  22.  
  23. #define BLKALLOC    10        /* Elements to allocate at a time */
  24. static XA_RECT_LIST *unused = NULL;    /* List of free elements */
  25. #define ALLOC(elem)    {                    \
  26.                 if (!unused)            \
  27.                     new_elements();        \
  28.                 elem = unused;            \
  29.                 unused = unused->next;    \
  30.             }
  31. #define FREE(elem)    {                    \
  32.                   elem->next = unused;    \
  33.                 unused = elem;            \
  34.             }
  35.  
  36. /*
  37.  *    Compute intersection of two rectangles; put result rectangle
  38.  *    into *d; return TRUE if intersection is nonzero.
  39.  *
  40.  *    (Original version of this function taken from Digital Research's
  41.  *    GEM sample application `DEMO' [aka `DOODLE'],  Version 1.1,
  42.  *    March 22, 1985)
  43.  */
  44.  
  45. short rc_intersect(const GRECT *s, GRECT *d)
  46. {
  47.     short x1, y1, x2, y2;
  48.  
  49.     x1 = max(s->g_x, d->g_x);
  50.     x2 = min(s->g_x + s->g_w, d->g_x + d->g_w);
  51.     if (x2 <= x1)
  52.         return(0);
  53.  
  54.     y1 = max(s->g_y, d->g_y);
  55.     y2 = min(s->g_y + s->g_h, d->g_y + d->g_h);
  56.     if (y2 <= y1)
  57.         return(0);
  58.  
  59.     d->g_x = x1;
  60.     d->g_y = y1;
  61.     d->g_w = x2 - x1;
  62.     d->g_h = y2 - y1;
  63.     return(1);
  64. }
  65.  
  66. static int intersect(const XA_RECT_LIST *s, const XA_WINDOW *d, XA_RECT_LIST *r)
  67. {
  68.     short x1, y1, x2, y2;
  69.  
  70.     x1 = max(s->x, d->x);
  71.     x2 = min(s->x + s->w, d->x + d->w);
  72.     if (x2 <= x1)
  73.         return(0);
  74.  
  75.     y1 = max(s->y, d->y);
  76.     y2 = min(s->y + s->h, d->y + d->h);
  77.     if (y2 <= y1)
  78.         return(0);
  79.     
  80.     r->x = x1;
  81.     r->y = y1;
  82.     r->w = x2 - x1;
  83.     r->h = y2 - y1;
  84.  
  85.     return(1);
  86. }
  87.  
  88. static int w_intersect(const XA_RECT_LIST *s, const XA_WINDOW *d, XA_RECT_LIST *r)
  89. {
  90.     short x1, y1, x2, y2;
  91.  
  92.     x1 = max(s->x, d->wx);
  93.     x2 = min(s->x + s->w, d->wx + d->ww);
  94.     if (x2 <= x1)
  95.         return(0);
  96.  
  97.     y1 = max(s->y, d->wy);
  98.     y2 = min(s->y + s->h, d->wy + d->wh);
  99.     if (y2 <= y1)
  100.         return(0);
  101.     
  102.     r->x = x1;
  103.     r->y = y1;
  104.     r->w = x2 - x1;
  105.     r->h = y2 - y1;
  106.  
  107.     return(1);
  108. }
  109.  
  110. static void new_elements(void)
  111. {
  112.     int i;
  113.     
  114.     unused = (XA_RECT_LIST *)malloc(BLKALLOC * sizeof(XA_RECT_LIST));
  115.     for(i = 0; i < BLKALLOC - 1; i++)
  116.         unused[i].next = &unused[i + 1];
  117.     unused[BLKALLOC - 1].next = NULL;
  118. #ifdef RL_DIAGS
  119.     DIAGS(("New rectangles (%ld)\n", (long)unused));
  120. #endif
  121. }
  122.  
  123.  
  124. XA_RECT_LIST *create_work_list(XA_WINDOW *w)
  125. {
  126.     XA_RECT_LIST *rl, *work, *cnrl, isect;
  127.     
  128.     rl = w->rl_full;
  129.     work = NULL;
  130.  
  131. #ifdef RL_DIAGS
  132.     DIAGS(("Creating new worklist\n"));
  133. #endif
  134.  
  135.     while(rl) {
  136.         if (w_intersect(rl, w, &isect)) {
  137.             ALLOC(cnrl);
  138.             cnrl->x = isect.x;
  139.             cnrl->y = isect.y;
  140.             cnrl->w = isect.w;        /* Was + 1 */
  141.             cnrl->h = isect.h;        /* Was + 1 */
  142.             cnrl->next = work;
  143.             work = cnrl;
  144.         }
  145.         rl = rl->next;
  146.     }
  147.     
  148.     return(work);
  149. }
  150.  
  151. static void free_rl_list(XA_RECT_LIST *list)
  152. {
  153.     XA_RECT_LIST *cur;
  154.  
  155.     if (!list)
  156.         return;
  157.  
  158.     cur = list;
  159.     while(cur->next)
  160.         cur = cur->next;
  161.     cur->next = unused;
  162.     unused = list;
  163. }
  164.  
  165. void invalidate_rect_lists(XA_WINDOW *wind)
  166. {
  167. #ifdef RL_DIAGS
  168.     DIAGS(("Invalidating lists\n"));
  169. #endif
  170.  
  171.     while(wind) {
  172.         free_rl_list(wind->rl_full);
  173.         wind->rl_full = NULL;
  174.         free_rl_list(wind->rl_work);
  175.         wind->rl_work = NULL;
  176.         wind = wind->next;
  177.     }
  178. }
  179.  
  180.  
  181. /*
  182.     Rectangle List Generator 
  183.     - generates a list of clipping rectangles for a given window.
  184. */
  185.  
  186. XA_RECT_LIST *generate_rect_list(XA_WINDOW *w)
  187. {
  188.     XA_WINDOW *wl;
  189.     XA_RECT_LIST *rl, *rlist, *nrl, *cnrl;
  190.     GRECT r_ours, r_win;
  191.     XA_RECT_LIST *rlnext, isect;
  192.  
  193. #ifdef RL_DIAGS
  194.     DIAGS(("Generating new rectlist\n"));
  195. #endif
  196.  
  197.     ALLOC(rlist);    
  198.     rlist->x = w->x;
  199.     rlist->y = w->y;
  200.     rlist->w = w->w;
  201.     rlist->h = w->h;
  202.     rlist->next = NULL;
  203.  
  204.     Psemaphore(2,WIN_LIST_SEMAPHORE,-1L);
  205.     
  206.     wl = w->prev;
  207.     while(wl) {
  208.         if (wl->is_open) {
  209.             nrl = NULL;
  210.             for(rl = rlist; rl; rl = rlnext) {
  211.                 rlnext = rl->next;
  212.                 if (!intersect(rl, wl, &isect)) {    /* Any overlap? */
  213.                     rl->next = nrl;                    /* Keep the current rectangle, */
  214.                     nrl = rl;                        /* it hasn't changed */
  215.                 } else {
  216.                     if ((rl->w != isect.w) || (rl->h != isect.h)) {    /* Not complete covering? */
  217.                         if (rl->x != isect.x) {                        /* Not at left border? */
  218.                             ALLOC(cnrl);
  219.                             cnrl->x = rl->x;
  220.                             cnrl->y = isect.y;
  221.                             cnrl->w = isect.x - rl->x;
  222.                             cnrl->h = isect.h;
  223.                             cnrl->next = nrl;
  224.                             nrl = cnrl;
  225.                         }
  226.                         if (isect.x + isect.w != rl->x + rl->w) {    /* Not at right border? */
  227.                             ALLOC(cnrl);
  228.                             cnrl->x = isect.x + isect.w;
  229.                             cnrl->y = isect.y;
  230.                             cnrl->w = rl->x + rl->w - (isect.x + isect.w);
  231.                             cnrl->h = isect.h;
  232.                             cnrl->next = nrl;
  233.                             nrl = cnrl;
  234.                         }
  235.                         if (isect.y != rl->y) {                        /* Not at top border? */
  236.                             ALLOC(cnrl);
  237.                             cnrl->x = rl->x;
  238.                             cnrl->y = rl->y;
  239.                             cnrl->w = rl->w;
  240.                             cnrl->h = isect.y - rl->y;
  241.                             cnrl->next = nrl;
  242.                             nrl = cnrl;
  243.                         }
  244.                         if(isect.y + isect.h != rl->y + rl->h) {    /* Not at bottom border? */
  245.                             ALLOC(cnrl);
  246.                             cnrl->x = rl->x;
  247.                             cnrl->y = isect.y + isect.h;
  248.                             cnrl->w = rl->w;
  249.                             cnrl->h = rl->y + rl->h - (isect.y + isect.h);
  250.                             cnrl->next = nrl;
  251.                             nrl = cnrl;
  252.                         }
  253.                         FREE(rl);        /* Now split, so throw away original!
  254.                     } else {
  255.                         FREE(rl);        /* Invisible - throw away! */
  256.                     }
  257.                 }
  258.             }
  259.             rlist = nrl;
  260.         }
  261.         wl = wl->prev;
  262.     }
  263.     
  264.     Psemaphore(3, WIN_LIST_SEMAPHORE, 0L);
  265.     
  266.     return(rlist);
  267. }
  268.